<template>
  <el-container>
    <!-- 左栏 -->
    <el-aside>
      <h1>任务配置</h1>
      <el-scrollbar>
        <el-form
          :model="config"
          label-position="top"
        >
          <!-- 触发时间 -->
          <el-form-item>
            <template #label>
              <div class="form-item-label">
                <span>触发时间</span>
                <el-switch
                  inline-prompt
                  v-model="config.enable"
                  @change="enableChange"
                  style="--el-switch-on-color: #67C23A; --el-switch-off-color: #F56C6C" 
                />
              </div>
            </template>
            <el-input
              readonly
              v-model="config.cronTime"
              @click="chooseCronTime" />
            <el-dialog
              title="选择触发时间"
              width="80%"
              :close-on-click-modal="false"
              :draggable="true"
              v-model="status.cronTime.editing"
            >
              <vue3-cron
                i18n="cn"
                :cron-value="config.cronTime"
                @change="cronTimeEditorChange"
                @close="cronTimeEditorClose" />
            </el-dialog>
          </el-form-item>
          <!-- 执行目标 -->
          <el-form-item>
            <template #label>
              <div class="form-item-label">
                <span>执行目标</span>
                <el-button
                  type="primary"
                  size="small"
                  @click="chooseExeFile"
                >选择</el-button>
              </div>
            </template>
            <el-input
              v-model="config.command"
              type="textarea"
              :autosize="{ minRows: 2, maxRows: 4 }" />
          </el-form-item>
          <!-- 执行参数 -->
          <el-form-item label="执行参数">
            <el-input
              v-model="config.args"
              type="textarea"
              :autosize="{ minRows: 8, maxRows: 16 }" />
          </el-form-item>
        </el-form>
        <!-- 按钮组 -->
        <el-button-group class="config-actions">
          <el-button
            type="primary"
            :icon="Check"
            @click="saveConfig"
          >保存</el-button>
          <el-button
            :icon="RefreshLeft"
            @click="loadConfig"
          >还原</el-button>
          <el-button
            :icon="Promotion"
            @click="runNow"
          >执行一次</el-button>
        </el-button-group>

        <div>
          <ce-cron-forecast
            ref="cronForecastRef"
            :cronTime="config.cronTime"/>
        </div>
      </el-scrollbar>
    </el-aside>

    <!-- 右栏 -->
    <el-main>
      <h1>历史记录</h1>
      <el-scrollbar
        class="history-scrollbar"
        ref="historyScrollbarRef"
      >
        <div
          class="history-list"
          ref="historyListRef"
        >
          <ce-history-item
            v-for="data in historyList"
            :key="data.time"
            :data="data"
            @click="showHistoryDetail(data)" />
        </div>
      </el-scrollbar>
      <el-dialog
        title="历史记录详情"
        v-model="status.history.showDetail"
        :close-on-click-modal="false"
        :fullscreen="true"
      >
        <ce-history-detail :data="status.history.detail" />
      </el-dialog>
    </el-main>
  </el-container>
</template>

<script setup>
import { ElMessage } from 'element-plus';
import { Promotion, Check, RefreshLeft } from '@element-plus/icons-vue'
import { reactive, ref } from 'vue';
import Vue3Cron from './components/vue3-cron'
import CeHistoryItem from './components/ce-history-item'
import ceHistoryDetail from './components/ce-history-detail'
import CeCronForecast from './components/ce-cron-forecast'

const config = reactive({
  enable: false,
  cronTime: '0 * * * * *',
  command: '',
  args: '',
  encoding: 'cp936',
})
const status = reactive({
  cronTime: {
    editing: false,
  },
  history: {
    detail: {},
    showDetail: false,
  }
})
const historyList = reactive([])
const historyJobs = {}

const historyScrollbarRef = ref()
const historyListRef = ref()
const cronForecastRef = ref()

// 触发时间相关方法
const enableChange = () => {
  window.cronApi.enable(config.enable)
}
const chooseCronTime = () => {
  status.cronTime.editing = true
  status.cronTime.tempValue = config.cronTime
}
const cronTimeEditorChange = (value) => {
  if (typeof value !== 'string') return false
  config.cronTime = value
}
const cronTimeEditorClose = () => {
  status.cronTime.editing = false
}

// 执行目标相关方法
const chooseExeFile = () => {
  const exts = ['exe', 'cmd', 'bat']
  let param = JSON.stringify(exts)

  window.connApi.chooseFile(param).then((data) => {
    if (data) {
      config.command = data[0]
    }
  }).catch((err) => {
    console.error('chooseExeFile error:', err)
  })
}

// 操作相关方法
const saveConfig = () => {
  // 去除头尾空白符
  config.cronTime = config.cronTime.trim()
  config.command = config.command.trim()
  config.args = config.args.trim()

  let param = JSON.stringify(config)
  window.cronApi.config(param).then(() => {
    ElMessage.success('任务配置保存成功')
  }).catch(() => {
    ElMessage.error('任务配置保存失败！')
  })
  loadConfig()
}
const runNow = () => {
  window.cronApi.runOnce().then(() => {
    ElMessage.success('任务开始执行')
  }).catch(() => {
    ElMessage.error('任务启动失败！')
  })
}
const loadConfig = () => {
  window.cronApi.config().then((data) => {
    Object.assign(config, data)
  }).catch(() => {
    ElMessage.error('获取任务配置失败！')
  })
}
const historyHandle = (event, data) => {
  console.log(event, data)
  switch (data.type) {
    case 'job_start': {
      historyList.push(data)
      let rData = historyList[historyList.length - 1]
      historyJobs[data.job.id] = rData
      break
    }
    case 'job_success':
    case 'job_fail':
    case 'job_kill': {
      let jobId = data.job.id
      if (jobId in historyJobs) {
        Object.assign(historyJobs[jobId], data)
        delete historyJobs[jobId]
      } else {
        historyList.push(data)
      }
      break
    }
    default:
      historyList.push(data)
  }

  // 删除过久的历史记录，上限1000条
  let redundant = historyList.length - 1000;
  if (redundant > 0) {
    historyList.splice(0, redundant)
  }

  // 自动滚动到底部
  setTimeout(() => {
      historyScrollbarRef.value.setScrollTop(historyListRef.value.clientHeight)
    },
    10
  )

  // 更新预报
  cronForecastRef.value.update()
}

const showHistoryDetail = (data) => {
  if (data.type === 'info') return
  status.history.detail = data
  status.history.showDetail = true
}

loadConfig()
window.cronApi.history((event, data) => historyHandle(event, data))
</script>

<style>
body {
  padding: 0;
  margin: 0;
}

.el-container {
  height: 100vh;
}

.el-container > .el-divider {
  height: 100%;
  margin: 0;
}

h1 {
  font-size: var(--el-font-size-extra-large);
  font-weight: normal;
}

.el-main, .el-aside {
  padding: 0;
  display: flex;
  flex-direction: column;
}
.el-main > *, .el-aside > * {
  padding-left: 16px;
  padding-right: 16px;
}

.el-aside {
  background-color: var(--el-bg-color-page);
}

.form-item-label {
  margin-right: -12px;
  display: flex;
  justify-content: space-between;
}

.config-actions {
  margin: 0 auto 64px;
}

.history-scrollbar {
  flex-grow: 1;
}

.history-list .ce-history-item {
  margin-bottom: 8px;
}
</style>
